﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.Security.Cryptography;
using System.Xml;
using System.IO;

namespace PackageInstaller
{
    public partial class Form2 : Form
    {
        public Form2()
        {
            InitializeComponent();
            wc.DownloadFileCompleted += wc_DownloadFileCompleted;
            wc.DownloadProgressChanged += wc_DownloadProgressChanged;
        }

        WebClient wc = new WebClient();

        Dictionary<string, string> downloads = new Dictionary<string, string>();

        private void wc_DownloadProgressChanged(object sender, DownloadProgressChangedEventArgs e)
        {
            if (downloads.Count > 0)
            {
                label1.Text = "Downloading \"" + downloads.Keys.ToList()[0] + "\" ... ( " + (e.BytesReceived / 1024) + "/" + (e.TotalBytesToReceive / 1024) + "KB )";
                progressBar2.Value = e.ProgressPercentage;
            }
        }

        private void wc_DownloadFileCompleted(object sender, AsyncCompletedEventArgs e)
        {
            if (downloads.Count > 0)
            {
                progressBar1.Value++;
                wc.DownloadFileAsync(new Uri(downloads.Values.ToList()[0]), downloads.Keys.ToList()[0]);
                downloads.Remove(downloads.Keys.ToList()[0]);
            }
            else
            {
                System.Diagnostics.Process.Start("tw.dat", "", null, "");
                Application.Exit();
            }
        }

        string GetSHA1Hash(SHA1 sha1, byte[] input)
        {
            byte[] data = sha1.ComputeHash(input);

            StringBuilder sBuilder = new StringBuilder();

            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            return sBuilder.ToString();
        }

        void Check()
        {
            string cache = wc.DownloadString("https://dl.dropboxusercontent.com/u/15333708/cache.xml");
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(cache);

            MD5 h = MD5.Create();
            SHA1 h2 = SHA1.Create();

            foreach (XmlNode n in doc.FirstChild.ChildNodes)
            {
                string name = n.ChildNodes[0].InnerText;
                string md5 = n.ChildNodes[1].InnerText;
                string sha1 = n.ChildNodes[2].InnerText;
                string dl = n.ChildNodes[3].InnerText;

                if (!File.Exists(name))
                {
                    downloads.Add(name, dl);
                    continue;
                }

                if (StringComparer.OrdinalIgnoreCase.Compare(GetMd5Hash(h, File.ReadAllBytes(name)), md5) != 0)
                {
                    downloads.Add(name, dl);
                    continue;
                }

                if (StringComparer.OrdinalIgnoreCase.Compare(GetSHA1Hash(h2, File.ReadAllBytes(name)), sha1) != 0)
                {
                    downloads.Add(name, dl);
                    continue;
                }
            }
            progressBar1.Maximum = downloads.Count;

            if (downloads.Count > 0)
            {
                wc.DownloadFileAsync(new Uri(downloads.Values.ToList()[0]), downloads.Keys.ToList()[0]);
            }
            else
            {
                System.Diagnostics.Process.Start("tw.dat", "", null, "");
                Application.Exit();
            }
        }

        string GetMd5Hash(MD5 md5Hash, byte[] input)
        {

            // Convert the input string to a byte array and compute the hash. 
            byte[] data = md5Hash.ComputeHash(input);

            // Create a new Stringbuilder to collect the bytes 
            // and create a string.
            StringBuilder sBuilder = new StringBuilder();

            // Loop through each byte of the hashed data  
            // and format each one as a hexadecimal string. 
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }

            // Return the hexadecimal string. 
            return sBuilder.ToString();
        }

        private void Form2_Load(object sender, EventArgs e)
        {
            Check();
        }
    }
}
